#pragma once

#include <atomic>
#include <memory>
#include <mutex>
#include <utility>
#include "Concurrency.h"

namespace std {
    template<class T> struct atomic<std::shared_ptr<T>> {
        void store(std::shared_ptr<T> desired) noexcept {
            std::lock_guard<spinlock> lock(lock_);
            ptr_ = std::move(desired);
        }
        std::shared_ptr<T> load() const noexcept {
            std::lock_guard<spinlock> lock(lock_);
            return ptr_;
        }
        mutable spinlock lock_;
        std::shared_ptr<T> ptr_;
    };
}

#if defined(__GNUC__)
#include <cstdio>
namespace std {
    inline void from_chars(const char *first, const char *last, float &value) {
        char fmt[13];
        std::snprintf(fmt, sizeof(fmt), "%%%df", int(last - first));
        std::sscanf(first, fmt, &value);
    }
    inline void from_chars(const char *first, const char *last, double &value) {
        char fmt[13];
        std::snprintf(fmt, sizeof(fmt), "%%%dlf", int(last - first));
        std::sscanf(first, fmt, &value);
    }
    inline void from_chars(const char *first, const char *last, long double &value) {
        char fmt[13];
        std::snprintf(fmt, sizeof(fmt), "%%%dLf", int(last - first));
        std::sscanf(first, fmt, &value);
    }
}
#endif
